#include "Common.h"
#include "ThreadCache.h"
#include "ObjectPool.h"
#include "CentralCache.h"
#include "PageCache.h"

// 针对每一个线程，都有一个ThreadCache对象（并且其他线程无法访问这个ThreadCache对象）
// 这个函数用来并发安全地分配内存
// 参数1：size-申请的内存大小
// 返回值：void*类型的指针，指向申请到的内存
void *ConcurrentAlloc(size_t size)
{
    if(size > MAX_BYTES)
    {
        size_t alignSize =SizeClass::RoundUp(size);
        size_t kpage = alignSize >> PAGE_SHIFT;
        PageCache::GetInstance()->GetMtx().lock();
        Span* span = PageCache::GetInstance()->NewSpan(kpage);
        span->_objSize = size;
        PageCache::GetInstance()->GetMtx().unlock();
        void* ptr = (void*)(span->_pageID << PAGE_SHIFT);
        return ptr;
    }
    else  
    {
        if (pTLSThreadCache == nullptr) // 如果当前线程的ThreadCache对象为空
        {
            static ObjectPool<ThreadCache> tcPool;
            // pTLSThreadCache = new ThreadCache; // 如果为空，就创建一个ThreadCache对象，并赋值给pTLSThreadCache
            pTLSThreadCache = tcPool.New();
        }
        return pTLSThreadCache->Allocate(size); // 返回从ThreadCache申请到的内存
    }
}

// 这个函数用来并发安全地释放内存
// 参数1：ptr-要释放的内存指针
// 参数2：size-要释放的内存大小
// 返回值：void类型
void ConcurrentFree(void *ptr)
{
    Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr);
    size_t size = span->_objSize;
    assert(pTLSThreadCache);                // 断言ThreadCache对象不为空
    pTLSThreadCache->Deallocate(ptr, size); // 调用ThreadCache的Deallocate函数，释放内存
}